package forestsimulatorp3.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

import forestsimulatorp3.model.simulator.ForestSimulator;

/**
 * The main window of the application.
 * @author dielson
 *
 */
public class MainWindow extends JFrame implements Runnable {

	// Constants ---------------------------------------------------------------

	private final static String LOOK_AND_FEEL = "Numbus";
	private final int HEIGHT_BOUNDS = 450;
	private final int WIDTH_BOUNDS = 600;

	// Attributes --------------------------------------------------------------

	ForestSimulator simulator;
	private JTextArea textArea;
	private JTextField cyclesField;
	private long numberOfCycles;

	// Constructors ------------------------------------------------------------

	public MainWindow() {
		super("Forest");

		simulator = new ForestSimulator(this);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(new Dimension(WIDTH_BOUNDS, HEIGHT_BOUNDS));
		setLocationRelativeTo(null);
		setLayout(new BorderLayout());

		addNorthPanel();
		addCentralPanel();
		addSouthPanel();

		initLookAndFeel();
	}

	// Public methods ----------------------------------------------------------

	public void notifyAction(String text) {
		textArea.setText(textArea.getText() + "\n" + text);
	}

	// Private methods ---------------------------------------------------------

	private void addNorthPanel() {
		JMenuBar menuBar = new JMenuBar();
		JMenu archieve = new JMenu("Arquivo");
		JMenuItem exit = new JMenuItem("Sair");
		exit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		archieve.add(exit);
		menuBar.add(archieve);

		add(menuBar, BorderLayout.NORTH);
	}

	private void addCentralPanel() {
		textArea = new JTextArea();
		textArea.setSize(100, 100);
		textArea.setEditable(false);

		JScrollPane scrollPane = new JScrollPane(textArea);
		//scrollPane.setAutoscrolls(true);
		add(scrollPane, BorderLayout.CENTER);
	}

	private void addSouthPanel() {
		JPanel southPanel = new JPanel();
		southPanel.setLayout(new FlowLayout());
		southPanel.setBorder(BorderFactory.createTitledBorder("Controles"));

		JLabel label = new JLabel("Número de ciclos:");
		cyclesField = new JTextField(8);
		cyclesField.setText("50");

		JButton buttonBegin = new JButton("Begin");

		buttonBegin.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				textArea.setText("");
				numberOfCycles = validateEntry();
				simulator.executeCycles(numberOfCycles);
			}
		});

		southPanel.add(label);
		southPanel.add(cyclesField);
		southPanel.add(buttonBegin);
		add(southPanel, BorderLayout.SOUTH);
	}

	/**
	 * Tries to initiate the defined look and feel.
	 */
	private void initLookAndFeel() {
		try {

			for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
				if (LOOK_AND_FEEL.equals(info.getName())) {
					UIManager.setLookAndFeel(info.getClassName());
				}
				//throw new ClassNotFoundException("Look and feel not found");
			}
		} catch (Exception e) {

			String message = "The look and feel could not be initializated.\n" +
					"Changing to default look and feel.";
			JOptionPane.showMessageDialog(this, message, "Warning",
					JOptionPane.WARNING_MESSAGE);
		}
	}

	private long validateEntry() {
		long entry; 
		try {
			entry = Long.parseLong(cyclesField.getText());
		} catch (NumberFormatException e) {
			String message = "Formato inválido";
			JOptionPane.showMessageDialog(this, message, "Erro", JOptionPane.ERROR_MESSAGE);
			entry = 50;
		}
		return entry;
	}

	// Getters & setters -------------------------------------------------------

	// Implements Runnable -----------------------------------------------------

	/**
	 * Puts the window to run.
	 */
	@Override
	public void run() {
		setVisible(true);
	}

	// Static methods ----------------------------------------------------------

	/**
	 * The main method of the program
	 */
	public static void main(String[] args) {
		MainWindow mainWindow = new MainWindow();
		mainWindow.run();
	}

	// Classes -----------------------------------------------------------------
}
